package com.santoker.baseservice.util;

import com.google.common.collect.Maps;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Field;
import java.util.*;
import java.util.Map.Entry;

public class MapUtil {

    /**
     * 使用 Map按key进行排序
     *
     * @param map
     * @return SortedMap<String, String>
     */
    public static SortedMap<String, String> sortedMap(Map<String, String> map) {
        if (map == null || map.isEmpty()) return null;
        SortedMap<String, String> sortMap = new TreeMap<String, String>(map);
        return sortMap;
    }

    /**
     * object转Map
     *
     * @param obj
     * @return Map<String, Object>
     */
    public static Map<String, Object> obj2Map(Object obj) throws Exception {
        Map<String, Object> result = new HashMap<String, Object>();
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            result.put(field.getName(), field.get(obj));
        }
        return result;
    }

    /**
     * object转Map
     *
     * @param obj
     * @return Map<String, String>
     */
    public static Map<String, String> objToMap(Object obj) throws Exception {
        Map<String, String> result = new HashMap<String, String>();
        String val = "";
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            val = (null == field.get(obj)) ? "" : String.valueOf(field.get(obj));
            result.put(field.getName(), val);
        }
        return result;
    }

    /**
     * map转字符串
     *
     * @param map
     * @return String
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    public static String map2Str(Map map) {
        String str = null;
        if (null != map) {
            Entry entry;
            StringBuffer sb = new StringBuffer();
            for (Iterator<Entry> entries = map.entrySet().iterator(); entries.hasNext(); ) {
                entry = entries.next();
                sb.append(entry.getKey().toString()).append("=")
                        .append(null == entry.getValue() ? "" : entry.getValue().toString())
                        .append(entries.hasNext() ? "&" : "");
            }
            str = sb.toString().trim();
        }
        return str;
    }

    /**
     * json字符串转Map
     *
     * @param json
     * @return Map
     */
    public static Map<String, Object> json2Map(String json) {
        Gson gson = new Gson();
        Map<String, Object> resMap = gson.fromJson(json, new TypeToken<Map<String, Object>>() {
        }.getType());
        return resMap;
    }

    /**
     * 获取新的Map
     *
     * @param map
     * @return Map<String, Object>
     */
    public static Map<String, Object> getNewMap(Map<String, Object> map) {
        Map<String, Object> retMap = new HashMap<String, Object>();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            retMap.put(entry.getKey(), entry.getValue());
        }
        return retMap;
    }

    /**
     * 过滤空值
     * 注：去除为null，或者空值的key
     *
     * @param map
     * @return Map<String, String>
     */
    public static Map<String, String> paramFilter(Map<String, String> map) {
        Map<String, String> result = new HashMap<String, String>();
        for (Map.Entry<String, String> entry : map.entrySet()) {
            if (null != entry.getValue() && !entry.getValue().isEmpty()) {
                result.put(entry.getKey(), entry.getValue());
            }
        }
        return result;
    }

    /**
     * Map<String, String> 转 Map<String, Object>
     *
     * @param param
     * @return
     */
    public static Map<String, Object> toObjectMap(Map<String, String> param) {
        Map<String, Object> data = Maps.newConcurrentMap();
        for (Map.Entry<String, String> entry : param.entrySet()) {
            System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
            data.put(entry.getKey(), entry.getValue());
        }
        return data;
    }

}
